package com.zenithmind.user.controller;

import com.zenithmind.common.annotation.Log;
import com.zenithmind.common.constant.OperationTypeEnum;
import com.zenithmind.common.result.PageResult;
import com.zenithmind.common.result.Result;
import com.zenithmind.user.controller.base.BaseController;
import com.zenithmind.user.pojo.domain.Tenant;
import com.zenithmind.user.pojo.dto.TenantCreateDTO;
import com.zenithmind.user.pojo.query.TenantQuery;
import com.zenithmind.user.pojo.vo.TenantVO;
import com.zenithmind.user.service.TenantService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 租户管理控制器
 * 遵循单一职责原则：专门处理租户管理相关功能
 * 遵循开闭原则：通过策略模式支持不同的租户操作
 *
 * @author ZenithMind
 * @since 2024-06-30
 */
@Slf4j
@RestController
@RequestMapping("/api/tenant")
@RequiredArgsConstructor
@Tag(name = "租户管理", description = "租户管理相关接口")
public class TenantController extends BaseController {

    private final TenantService tenantService;

    @Log(description = "创建租户", operationType = OperationTypeEnum.ADD)
    @PostMapping
    @Operation(summary = "创建租户", description = "创建新的租户")
    @PreAuthorize("hasRole('SUPER_ADMIN')")
    public Result<TenantVO> createTenant(@Valid @RequestBody TenantCreateDTO createDTO) {
        logOperation("创建租户", createDTO.getTenantCode());

        try {
            Result<TenantVO> result = tenantService.createTenant(createDTO);
            if (result.isSuccess()) {
                logSuccess("创建租户", createDTO.getTenantCode());
            } else {
                logFailure("创建租户", result.getMsg());
            }
            return result;
        } catch (Exception e) {
            logFailure("创建租户", e.getMessage());
            throw e;
        }
    }

    @GetMapping("/page")
    @Operation(summary = "分页查询租户", description = "分页查询租户列表")
    @PreAuthorize("hasRole('SUPER_ADMIN')")
    public Result<PageResult<TenantVO>> getTenantPage(@Parameter(description = "查询条件") TenantQuery query) {
        log.info("分页查询租户: {}", query);
        PageResult<TenantVO> result = tenantService.getTenantPage(query);
        return Result.success(result);
    }

    @GetMapping("/{id}")
    @Operation(summary = "获取租户详情", description = "根据ID获取租户详细信息")
    @PreAuthorize("hasRole('SUPER_ADMIN')")
    public Result<TenantVO> getTenantById(@Parameter(description = "租户ID") @PathVariable String id) {
        log.info("获取租户详情: {}", id);
        TenantVO tenant = tenantService.getTenantById(id);
        if (tenant == null) {
            return Result.fail("租户不存在");
        }
        return Result.success(tenant);
    }

    @GetMapping("/code/{tenantCode}")
    @Operation(summary = "根据编码获取租户", description = "根据租户编码获取租户信息")
    @PreAuthorize("hasRole('SUPER_ADMIN')")
    public Result<TenantVO> getTenantByCode(@Parameter(description = "租户编码") @PathVariable String tenantCode) {
        log.info("根据编码获取租户: {}", tenantCode);
        TenantVO tenant = tenantService.getTenantByCode(tenantCode);
        if (tenant == null) {
            return Result.fail("租户不存在");
        }
        return Result.success(tenant);
    }

    @PutMapping
    @Operation(summary = "更新租户", description = "更新租户信息")
    @PreAuthorize("hasRole('SUPER_ADMIN')")
    public Result<TenantVO> updateTenant(@Valid @RequestBody Tenant tenant) {
        log.info("更新租户: {}", tenant.getId());
        return tenantService.updateTenant(tenant);
    }

    @PutMapping("/{id}/status")
    @Operation(summary = "更新租户状态", description = "启用或禁用租户")
    @PreAuthorize("hasRole('SUPER_ADMIN')")
    public Result<Void> updateTenantStatus(
            @Parameter(description = "租户ID") @PathVariable String id,
            @Parameter(description = "状态") @RequestParam Integer status) {
        log.info("更新租户状态: {} -> {}", id, status);
        return tenantService.updateTenantStatus(id, status);
    }

    @DeleteMapping("/{id}")
    @Operation(summary = "删除租户", description = "删除指定租户")
    @PreAuthorize("hasRole('SUPER_ADMIN')")
    public Result<Void> deleteTenant(@Parameter(description = "租户ID") @PathVariable String id) {
        log.info("删除租户: {}", id);
        return tenantService.deleteTenant(id);
    }

    @DeleteMapping("/batch")
    @Operation(summary = "批量删除租户", description = "批量删除多个租户")
    @PreAuthorize("hasRole('SUPER_ADMIN')")
    public Result<Void> deleteTenantBatch(@Parameter(description = "租户ID列表") @RequestBody List<String> ids) {
        log.info("批量删除租户: {}", ids);
        return tenantService.deleteTenantBatch(ids);
    }

    @GetMapping("/expiring-soon")
    @Operation(summary = "获取即将到期的租户", description = "获取7天内即将到期的租户列表")
    @PreAuthorize("hasRole('SUPER_ADMIN')")
    public Result<List<TenantVO>> getExpiringSoonTenants() {
        log.info("获取即将到期的租户");
        List<TenantVO> tenants = tenantService.getExpiringSoonTenants();
        return Result.success(tenants);
    }

    @GetMapping("/expired")
    @Operation(summary = "获取已过期的租户", description = "获取已过期的租户列表")
    @PreAuthorize("hasRole('SUPER_ADMIN')")
    public Result<List<TenantVO>> getExpiredTenants() {
        log.info("获取已过期的租户");
        List<TenantVO> tenants = tenantService.getExpiredTenants();
        return Result.success(tenants);
    }

    @GetMapping("/stats")
    @Operation(summary = "获取租户统计", description = "获取租户统计信息")
    @PreAuthorize("hasRole('SUPER_ADMIN')")
    public Result<TenantVO> getTenantStats() {
        log.info("获取租户统计信息");
        TenantVO stats = tenantService.getTenantStats();
        return Result.success(stats);
    }

    @PostMapping("/{tenantId}/storage/increment")
    @Operation(summary = "增加租户存储使用量", description = "增加或减少租户存储使用量")
    @PreAuthorize("hasRole('SUPER_ADMIN') or hasRole('ADMIN')")
    public Result<Void> incrementStorageUsed(
            @Parameter(description = "租户ID") @PathVariable String tenantId,
            @Parameter(description = "增量（字节，可为负数）") @RequestParam Long increment) {
        log.info("增加租户存储使用量: {} -> {}", tenantId, increment);
        boolean success = tenantService.incrementStorageUsed(tenantId, increment);
        if (success) {
            return Result.success();
        }
        return Result.fail("更新存储使用量失败");
    }

    @GetMapping("/{tenantId}/valid")
    @Operation(summary = "检查租户是否有效", description = "检查租户状态是否有效")
    public Result<Boolean> isTenantValid(@Parameter(description = "租户ID") @PathVariable String tenantId) {
        log.info("检查租户是否有效: {}", tenantId);
        boolean valid = tenantService.isTenantValid(tenantId);
        return Result.success(valid);
    }
}
